package com.tm.media.login.aop;

import cn.hutool.extra.servlet.ServletUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.tm.media.login.service.SysLogService;
import com.tm.media.model.entity.AdUserOpertion;
import com.tm.media.login.annotation.SysAnnotation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Map;

@Configuration
@Aspect
@Slf4j
public class SysLogAop {
    @Autowired
    private SysLogService sysLogService;


   /* public void operationLogPointCut() {
    }
    @Before("operationLogPointCut()")
    public void before(){
        log.info("前置通知=======================================================");
    }
    @After("operationLogPointCut()")
    public void after(){
        log.info("后置通知=======================================================");
    }
    @Around("operationLogPointCut()")
    public Object around1(ProceedingJoinPoint joinPoint){
        log.info("环绕通知开始=======================================================");
        Object proceed=null;
        try {
             proceed = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        log.info("环绕通知结束=======================================================");
        return proceed;
    }
    @AfterReturning("operationLogPointCut()")
    public void afterReturning(){
        log.info("返回后通知=======================================================");
    }
    @AfterThrowing("operationLogPointCut()")
    public void afterThrowing(){
        log.info("抛出异常通知=======================================================");
    }
*/
    /**
     * 设置操作日志切入点，在注解的位置切入代码
     */
    @Pointcut("execution(* com.tm.media.login.controller.ApUserIdentityController.*(..))")
    public void operationLogPointCut() {
    }
    /**
     * 定义环绕通知
     * 1. 环绕通知需要携带ProceedingJoinPoint类型的参数
     * 2. 环绕通知类似于动态代理的全过程ProceedingJoinPoint类型的参数可以决定是否执行目标方法
     * 3. 且环绕通知必须有返回值，返回值即目标方法的返回值
     */
    @Around("operationLogPointCut()")
    public Object   around(ProceedingJoinPoint joinPoint) throws JsonProcessingException {
        Object result=null;
        log.info("请求开始");
        AdUserOpertion entity = new AdUserOpertion();
       //获取系统当前毫秒值
        LocalDateTime startNow = LocalDateTime.now();
        //执行目标方法
        try {
          result= joinPoint.proceed();
       } catch (Throwable e) {
           e.printStackTrace();
       }
        // 获取RequestAttributes
       RequestAttributes RequestAttributes= RequestContextHolder.getRequestAttributes();
        // 从获取RequestAttributes中获取HttpServletRequest的信息  request上下文
       HttpServletRequest request =(HttpServletRequest)RequestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        //获取到请求的URI
       String requestURI = request.getRequestURI();
      // entity.setUri(requestURI);
        //获取到请求的URL
        StringBuffer requestURL = request.getRequestURL();
        //  entity.setUrl(requestURL.toString());
        //获取请求路径的参数
        Map<String, String> paramMap = ServletUtil.getParamMap(request);

       //将参数转换为JSON格式
       //String canshu = JSONObject.toJSONString(paramMap);
       // entity.setRequestParams(canshu);
        //从切面织入点出通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();
        //获取操作
        SysAnnotation annotation = method.getAnnotation(SysAnnotation.class);
        if(annotation!=null){
            entity.setDescription(annotation.description());
            entity.setType(annotation.logType().getOperationType());
        }else {
            //获取请求的类名
            String className = joinPoint.getTarget().getClass().getName();
            //获取请求的方法名
            String methodName=method.getName();
            methodName=className+"."+methodName;
            entity.setDescription(methodName);
        }
         // 返回结果
         // entity.setResponseParams(new ObjectMapper().writeValueAsString(result));
       // 请求用户的ID
         entity.setId(1);
      // 请求用户的名字
        entity.setUserId(3);
        //获取IP
        String ip = ServletUtil.getClientIP(request);
        entity.setIp(ip);
        LocalDateTime endNow = LocalDateTime.now();
        long longEndNow = endNow.toInstant(ZoneOffset.ofTotalSeconds(+8)).toEpochMilli();
        long startEndNow = startNow.toInstant(ZoneOffset.ofTotalSeconds(+8)).toEpochMilli();
        //  entity.setUsageTime(longEndNow-startEndNow);
       // 创建时间
       //   entity.setCreateTime(LocalDateTime.now());
    // 新增到数据库
        sysLogService.save(entity);
        log.info("请求结束");
        return  result;
    }

}

